/*
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
*/
#include "car_server.h"

CarHardwareUart::CarHardwareUart()
{
    LOGOUT_D("Create CarHardwareUart use default\n");
    uart_init(CN_CAR_UART_DEFAULT_PATH,CN_CAR_UART_DEFAULT_SPEED);
}

CarHardwareUart::CarHardwareUart(char *path)
{
    LOGOUT_D("Create CarHardwareUart path = %s \n",path);
    uart_init(path,CN_CAR_UART_DEFAULT_SPEED);
}

CarHardwareUart::CarHardwareUart(int speed)
{
    LOGOUT_D("Create CarHardwareUart speed = %d \n",speed);
    uart_init(CN_CAR_UART_DEFAULT_PATH,speed);
}

CarHardwareUart::CarHardwareUart(char *path,int speed)
{
    LOGOUT_D("Create CarHardwareUart object:mDevPath=%s,speed=%d\n",path,speed);
    uart_init(path,speed);
}

CarHardwareUart::~CarHardwareUart()
{
    LOGOUT_D("Create CarHardwareUart object\n");
}

void CarHardwareUart::uart_init(char *path, int speed)
{
    sprintf(mDevPath,"%s",path);
    mPara.uart.speed = speed;
    mfd = -1;
    LOGOUT_D("CarHardwareUart CarHardwareUart:mDevPath=%s,speed=%d\n",mDevPath,speed);
}

//===================================================================================
#define PARITY_NONE                     0
#define PARITY_ODD                      1
#define PARITY_EVE                      2
#define UART_DEFAULT_SPEED_INDEX        7
int CarHardwareUart::uart_set(int fd, int speed,int bits,int stop_bits,int parity)
{
	unsigned int i;
	struct termios   Opt;
	int search = UART_DEFAULT_SPEED_INDEX;

    const int speed_arr[] = { B1200,B2400,B4800, B9600, B19200, B38400,B57600,B115200,B230400,B460800,
        B500000,B576000,B921600,B1000000,B1152000,B1500000,B2000000,B2500000,B3000000,B3500000,B4000000
    };

    const int name_arr[] =  {  1200, 2400, 4800,  9600,  19200,  38400, 57600, 115200, 230400,460800,
         500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000
    };

	for(i = 0; i < sizeof(speed_arr)/sizeof(speed_arr[0]); i++){
		if(speed == name_arr[i]){
			search = i;
		}
	}

	if(tcgetattr(fd, &Opt) != 0){
		LOGOUT_E("Get option error\n");
		return -1;
	}

	switch(stop_bits){
		case 1:Opt.c_cflag &= ~CSTOPB;break;
		case 2:Opt.c_cflag |= ~CSTOPB;break;
		default:LOGOUT_E("Unsport stopbits\n");return -1;
	}

	Opt.c_cflag &= ~CSIZE;
	switch(bits){
		case 5:Opt.c_cflag |= CS5;break;
		case 6:Opt.c_cflag |= CS6;break;
		case 7:Opt.c_cflag |= CS7;break;
		case 8:Opt.c_cflag |= CS8;break;
		default:LOGOUT_E("Unsuported data size\n");return -1;
	}

	switch(parity){
		case PARITY_NONE:Opt.c_cflag &= ~PARENB;Opt.c_iflag &= ~INPCK;break;
		case PARITY_ODD:Opt.c_cflag |= (PARENB | PARODD);Opt.c_iflag |= INPCK;break;
		case PARITY_EVE:Opt.c_cflag |= PARENB;Opt.c_cflag &= ~PARODD;Opt.c_iflag |= INPCK;break;
		default:LOGOUT_E("Unspported parity!\n");return -1;
	}


	Opt.c_cflag |= (CLOCAL | CREAD);	//enable receive
	Opt.c_lflag = 0;
	Opt.c_oflag &= ~OPOST;		//OUT
	Opt.c_iflag &= ~(ICRNL | IXON | BRKINT | ISTRIP);
	Opt.c_cc[VMIN] = 0; //Opt.c_cc[VMIN] = 0;
	Opt.c_cc[VTIME] = 0;

	tcflush(fd, TCIOFLUSH);
	cfsetispeed(&Opt, speed_arr[search]);
	cfsetospeed(&Opt, speed_arr[search]);

	if(tcsetattr(fd, TCSANOW, &Opt) != 0){
		perror("tcsetattr fd1");
		return -1;
	}
	return 0;
}

int CarHardwareUart::HardwareOpen(car_hardware_param_t* param)
{
    int fd,ret;
    fd = open(mDevPath,O_RDWR);// | O_NOCTTY);// | O_NDELAY);
    if(fd < 0){
        return -1;
    }

    ret = uart_set(fd,param.uart.speed,8,1,0);
    if(ret < 0){
        close(fd);
        return ret;
    }

    mfd = fd;
    return fd;
}

void CarHardwareUart::HardwareClose()
{
    int ret = 0;
    if(mfd > 0){
        ret = close(mfd);
        mfd = -1;
    }
    return ret;
}

int CarHardwareUart::HardwareSetParam(car_hardware_param_t* param)
{
    return 0;
}

int CarHardwareUart::HardwareGetParam(car_hardware_param_t* param)
{
    return 0;
}

int CarHardwareUart::HardwareSend(char* src,int len)
{
    if(mfd<0){
        return -1;
    }

    return write(mfd,src,len);
}

int CarHardwareUart::HardwareRead(char* outbuf,int outbuf_len,int maxtime);
{
    int ret;
    fd_set fds;
    struct timeval tv;

    if(mfd<0){
        return -1;
    }

    tv.tv_sec = maxtime / 1000;
    tv.tv_usec = (maxtime % 1000) * 1000;

    FD_ZERO(&fds);
    FD_SET(g_fdMcuTTy, &fds);

    ret = select(mfd+1, &fds, NULL, NULL, &tv);
    if(ret <= 0){
        return ret;
    }

    return read(mfd,outbuf,outbuf_len);
}

